import { minioClient, DEFAULT_BUCKET } from '../config/minio';
import { generateTimestampNumericUUID } from '../utils/uuid';
import path from 'path';

export interface UploadResult {
  fileName: string;
  originalName: string;
  size: number;
  mimeType: string;
  url: string;
}

export class FileService {
  /**
   * 上传文件到MinIO
   */
  static async uploadFile(
    buffer: Buffer,
    originalName: string,
    mimeType: string
  ): Promise<UploadResult> {
    try {
      // 生成唯一文件名
      const fileExtension = path.extname(originalName);
      const fileName = `${generateTimestampNumericUUID()}${fileExtension}`;
      
      // 确保文件名只包含安全字符（避免中文等特殊字符）
      const safeFileName = fileName.replace(/[^a-zA-Z0-9.-]/g, '_');
      
      console.log('Original name:', originalName);
      console.log('Generated safe name:', safeFileName);
      
      // 上传文件
      await minioClient.putObject(DEFAULT_BUCKET, safeFileName, buffer, buffer.length, {
        'Content-Type': mimeType,
        'Original-Name': Buffer.from(originalName, 'utf8').toString('base64'), // 用base64编码保存原始文件名
      });

      // 生成访问URL
      const url = await this.getFileUrl(safeFileName);

      return {
        fileName: safeFileName,
        originalName,
        size: buffer.length,
        mimeType,
        url,
      };
    } catch (error) {
      console.error('Error uploading file to MinIO:', error);
      console.error('File details:', { originalName, mimeType, bufferSize: buffer.length });
      throw new Error('文件上传失败');
    }
  }

  /**
   * 获取文件访问URL
   */
  static async getFileUrl(fileName: string, expiry: number = 7 * 24 * 60 * 60): Promise<string> {
    try {
      return await minioClient.presignedGetObject(DEFAULT_BUCKET, fileName, expiry);
    } catch (error) {
      console.error('Error generating file URL:', error);
      throw new Error('获取文件URL失败');
    }
  }

  /**
   * 删除文件
   */
  static async deleteFile(fileName: string): Promise<void> {
    try {
      await minioClient.removeObject(DEFAULT_BUCKET, fileName);
    } catch (error) {
      console.error('Error deleting file from MinIO:', error);
      throw new Error('删除文件失败');
    }
  }

  /**
   * 获取文件信息
   */
  static async getFileInfo(fileName: string) {
    try {
      return await minioClient.statObject(DEFAULT_BUCKET, fileName);
    } catch (error) {
      console.error('Error getting file info:', error);
      throw new Error('获取文件信息失败');
    }
  }

  /**
   * 列出所有文件
   */
  static async listFiles(prefix?: string): Promise<string[]> {
    try {
      const files: string[] = [];
      const stream = minioClient.listObjects(DEFAULT_BUCKET, prefix, true);
      
      return new Promise((resolve, reject) => {
        stream.on('data', (obj) => {
          if (obj.name) files.push(obj.name);
        });
        stream.on('end', () => resolve(files));
        stream.on('error', reject);
      });
    } catch (error) {
      console.error('Error listing files:', error);
      throw new Error('获取文件列表失败');
    }
  }
}